package ae.pcfc.cldos.online.common.facade.provider;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.ws.client.WebServiceIOException;
import org.springframework.ws.soap.client.SoapFaultClientException;

import ae.pcfc.cldos.online.common.clddb.domain.manager.AppMetaDataDOM;
import ae.pcfc.cldos.online.common.etksdb.domain.Client;
import ae.pcfc.cldos.online.common.etksdb.domain.User;
import ae.pcfc.cldos.online.common.etksdb.domain.manager.ClientDOM;
import ae.pcfc.cldos.online.common.etksdb.domain.manager.UserDomainObjectManager;
import ae.pcfc.cldos.online.common.exception.FNPAppException;
import ae.pcfc.cldos.online.common.exception.GSAppException;
import ae.pcfc.cldos.online.common.exception.NoSuchCompanyException;
import ae.pcfc.cldos.online.common.facade.BaseFacade;
import ae.pcfc.cldos.online.common.facade.CompanyInformationFacade;
import ae.pcfc.cldos.online.common.manager.FNPManager;
import ae.pcfc.cldos.online.common.manager.GsInfoManager;
import ae.pcfc.cldos.online.common.tscdb.domain.TTscClientCompany;
import ae.pcfc.cldos.online.common.tscdb.domain.manager.TTscClientCompanyDOM;
import ae.pcfc.cldos.online.common.vo.CompanyInformationVO;
import ae.pcfc.cldos.online.common.vo.UserVO;
import ae.pcfc.cldos.online.fnp.service.client.vo.FNPAccountTypeVO;
import ae.pcfc.cldos.online.gs.service.client.vo.GSFinancialDataVO;

/**
 * 
 * @author arosa
 *
 */
public class CompanyInformationFacadeImpl extends BaseFacade implements CompanyInformationFacade {

	private UserDomainObjectManager userDomainObjectManager;
	private AppMetaDataDOM appMetaDataDOM;
	private ClientDOM clientDOM;
	
	private List<CompanyInformationVO> companyList;
	private Date lastInvocationTime = new Date();
	
	public ClientDOM getClientDOM() {
		return clientDOM;
	}

	public void setClientDOM(ClientDOM clientDOM) {
		this.clientDOM = clientDOM;
	}

	public AppMetaDataDOM getAppMetaDataDOM() {
		return appMetaDataDOM;
	}

	public void setAppMetaDataDOM(AppMetaDataDOM appMetaDataDOM) {
		this.appMetaDataDOM = appMetaDataDOM;
	}

	public void setUserDomainObjectManager(
			UserDomainObjectManager userDomainObjectManager) {
		this.userDomainObjectManager = userDomainObjectManager;
	}
	
	private TTscClientCompanyDOM tscClientCompanyDOM;
	
	public void setTscClientCompanyDOM(TTscClientCompanyDOM tscClientCompanyDOM) {
		this.tscClientCompanyDOM = tscClientCompanyDOM;
	}
	
	private GsInfoManager gsInfoManager;
	
	public void setGsInfoManager(GsInfoManager gsInfoManager) {
		this.gsInfoManager = gsInfoManager;
	}
	
	private FNPManager fnpManager;
	
	public void setFnpManager(FNPManager fnpManager) {
		this.fnpManager = fnpManager;
	}
	/**
	 * @param userVO
	 * @return
	 * @throws NoSuchCompanyException
	 * @throws GSAppException
	 * @throws FNPAppException
	 */
	@Transactional
	public CompanyInformationVO retriveGSInformation(UserVO userVO) throws NoSuchCompanyException,GSAppException{
		User user = userDomainObjectManager.findUserAndClientByUserName(userVO.getUsername());
		//call method to fetch company
		TTscClientCompany tTscClientCompany = 
				tscClientCompanyDOM.getCompanyByTrakheesId(user.getClient().getCTrakheesId());
		
		if(tTscClientCompany==null){
			throw new NoSuchCompanyException("No company for this user");
		}
		
		CompanyInformationVO companyInformationVO = new CompanyInformationVO();
		companyInformationVO.setCompanyName(tTscClientCompany.getCcName());
		//abed
		companyInformationVO.setCompanyNameAr(tTscClientCompany.getCcNameArb());
		companyInformationVO.setCompanyLicenseNo(tTscClientCompany.getCcLicNo());
		companyInformationVO.setAddress(tTscClientCompany.getCcAddress());
		//abed
		companyInformationVO.setAddressAr(tTscClientCompany.getCcAddressArb());
		GSFinancialDataVO gsFinantialVO =  null;
		
		try{
			gsFinantialVO =  gsInfoManager.retriveFinancialData(tTscClientCompany.getCcLicNo(),user.getClientId());
		}catch (WebServiceIOException e) {
			e.printStackTrace();
			throw new GSAppException(e);
		}catch (SoapFaultClientException e) {
			e.printStackTrace();
			throw new GSAppException(e);
		}catch(Exception e){
			throw new NoSuchCompanyException(e);
		}
		getMapper().map(gsFinantialVO, companyInformationVO);
		return companyInformationVO;
	}
	/**
	 * @param userVO
	 * @return
	 * @throws NoSuchCompanyException
	 * @throws GSAppException
	 * @throws FNPAppException
	 */
	@Transactional
	public CompanyInformationVO retriveFNPInformation(UserVO userVO) throws NoSuchCompanyException,FNPAppException{
		User user = userDomainObjectManager.findUserAndClientByUserName(userVO.getUsername());
		//call method to fetch company
		TTscClientCompany tTscClientCompany = 
				tscClientCompanyDOM.getCompanyByTrakheesId(user.getClient().getCTrakheesId());
		
		if(tTscClientCompany==null){
			throw new NoSuchCompanyException("No company for this user");
		}
		CompanyInformationVO companyInformationVO = new CompanyInformationVO();
		try{
			FNPAccountTypeVO fNPAccountTypeVO = fnpManager.enquireDeposits(tTscClientCompany.getCcTrakheesId());
			companyInformationVO.setPrepaidAccBalance(fNPAccountTypeVO.getPrepaidAccBalance());
			companyInformationVO.setReservedAccBalance(fNPAccountTypeVO.getReservedAccBalance());
		}catch(Exception e){
			throw new FNPAppException(e);
		}
		
		return companyInformationVO;
	}
	
	@Transactional
	public CompanyInformationVO retriveCompanyInformation(UserVO userVO) throws NoSuchCompanyException,GSAppException,FNPAppException{
		User user = userDomainObjectManager.findUserAndClientByUserName(userVO.getUsername());
		//call method to fetch company
		TTscClientCompany tTscClientCompany = 
				tscClientCompanyDOM.getCompanyByTrakheesId(user.getClient().getCTrakheesId());
		
		if(tTscClientCompany==null){
			throw new NoSuchCompanyException("No company for this user");
		}
		
		CompanyInformationVO companyInformationVO = new CompanyInformationVO();
		companyInformationVO.setCompanyName(tTscClientCompany.getCcName());
		companyInformationVO.setCompanyLicenseNo(tTscClientCompany.getCcLicNo());
		companyInformationVO.setAddress(tTscClientCompany.getCcAddress());
		GSFinancialDataVO gsFinantialVO =  null;
		
		try{
			gsFinantialVO =  gsInfoManager.retriveFinancialData(tTscClientCompany.getCcLicNo(),user.getClientId());
		} catch (WebServiceIOException e) {
			throw new GSAppException(e);
		}catch (SoapFaultClientException e) {
			throw new GSAppException(e);
		}catch(Exception e){
			throw new NoSuchCompanyException(e);
		}
		
		getMapper().map(gsFinantialVO, companyInformationVO);
		try{
			FNPAccountTypeVO fNPAccountTypeVO = fnpManager.enquireDeposits(tTscClientCompany.getCcTrakheesId());
			companyInformationVO.setPrepaidAccBalance(fNPAccountTypeVO.getPrepaidAccBalance());
			companyInformationVO.setReservedAccBalance(fNPAccountTypeVO.getReservedAccBalance());
		}catch(Exception e){
			throw new FNPAppException(e);
		}
		
		return companyInformationVO;
	}

	
	@Transactional
	public void setMedicalType(UserVO userVO, String medicalType) throws NoSuchCompanyException{
		
		User user = userDomainObjectManager.findUserAndClientByUserName(userVO.getUsername());
		
		//call method to fetch company
		TTscClientCompany tTscClientCompany = 
				tscClientCompanyDOM.getCompanyByTrakheesId(user.getClient().getCTrakheesId());
		
		if(tTscClientCompany==null){
			throw new NoSuchCompanyException("No company for this user");
		}
		
		try{
			gsInfoManager.setClientMedicalType(tTscClientCompany.getCcLicNo(), medicalType);			
		} catch (Exception e) {
			throw new NoSuchCompanyException(e);
		}
		
		return;
	}

	@Transactional
	public String getMedicalType(UserVO userVO) throws NoSuchCompanyException {
		
		User user = userDomainObjectManager.findUserAndClientByUserName(userVO.getUsername());
		
		//call method to fetch company
		TTscClientCompany tTscClientCompany = 
				tscClientCompanyDOM.getCompanyByTrakheesId(user.getClient().getCTrakheesId());
		
		if(tTscClientCompany==null){
			throw new NoSuchCompanyException("No company for this user");
		}
		
		String medicalType = null;

		try {
			medicalType = gsInfoManager.getClientMedicalType(tTscClientCompany.getCcLicNo());
		} catch (Exception e) {
			throw new NoSuchCompanyException(e);
		}
		
		return medicalType;		
	}
	

	/**
	 * @param licNo
	 * @param clientId
	 * @param tksId
	 * @return
	 * @throws NoSuchCompanyException
	 */
	@Transactional
	public CompanyInformationVO retriveTksAdminCompanyInformation(String licNo,Long clientId, String tksId) throws NoSuchCompanyException{
		CompanyInformationVO companyInformationVO = new CompanyInformationVO();
		GSFinancialDataVO gsFinantialVO =  null;
		try{
			gsFinantialVO =  gsInfoManager.retriveFinancialData(licNo,clientId);
		} catch (Exception e) {
			throw new NoSuchCompanyException(e);
		}
		getMapper().map(gsFinantialVO, companyInformationVO);
		FNPAccountTypeVO fNPAccountTypeVO = fnpManager.enquireDeposits(tksId);
		companyInformationVO.setPrepaidAccBalance(fNPAccountTypeVO.getPrepaidAccBalance());
		companyInformationVO.setReservedAccBalance(fNPAccountTypeVO.getReservedAccBalance());
		return companyInformationVO;
	}
	
	/**
	 * @return  List<CompanyInformationVO>
	 */
	@Transactional
	public synchronized List<CompanyInformationVO> getAllActiveCompanies(){
		Date currentTime = new Date();
		long diffr = lastInvocationTime.getTime() - currentTime.getTime(); 
		double diffInHours = diffr / ((double) 1000 * 60 * 60);   
		if(companyList==null || companyList.size()<=1 || diffInHours>1){
			companyList = new ArrayList<CompanyInformationVO>();
			CompanyInformationVO companyInfoVO = new CompanyInformationVO();
			companyList.add(companyInfoVO);
			List<TTscClientCompany> tscCompanyList = tscClientCompanyDOM.getAllActiveCompanies();
			List<Client> clientList =  clientDOM.getAllActiveClients();
			if(clientList!=null && clientList.size()!=0 && tscCompanyList!=null && tscCompanyList.size()!=0){
				for(Client client:clientList){
					for(TTscClientCompany tTscClientCompany:tscCompanyList){
						if(client.getCTrakheesId().equals(tTscClientCompany.getCcTrakheesId())){
							CompanyInformationVO companyInformationVO = new CompanyInformationVO();
							companyInformationVO.setCompanyName(tTscClientCompany.getCcName());
							companyInformationVO.setCompanyNameAr(tTscClientCompany.getCcNameArb());
							companyInformationVO.setCompanyLicenseNo(tTscClientCompany.getCcLicNo());
							companyInformationVO.setTksClientId(client.getCId());
							companyInformationVO.setTksId(tTscClientCompany.getCcTrakheesId());
							companyList.add(companyInformationVO);
							break;
						}
					}
				}
				
			}
		}
		return companyList;
	}

}
